<!doctype html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="BeagleBoneBlack," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />






<meta name="description" content="A few months back I got hold of my first BeagleBone Black (BBB) with the intention of installing it in my car as a trackday data logger. First step in this endeavor was to get the CANBus working. I wr">
<meta property="og:type" content="article">
<meta property="og:title" content="BBB添加CAN支持">
<meta property="og:url" content="http://ideask.cf/2017/04/27/bbb-build-can/index.html">
<meta property="og:site_name" content="Jason Lin">
<meta property="og:description" content="A few months back I got hold of my first BeagleBone Black (BBB) with the intention of installing it in my car as a trackday data logger. First step in this endeavor was to get the CANBus working. I wr">
<meta property="og:updated_time" content="2017-04-27T10:05:11.873Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="BBB添加CAN支持">
<meta name="twitter:description" content="A few months back I got hold of my first BeagleBone Black (BBB) with the intention of installing it in my car as a trackday data logger. First step in this endeavor was to get the CANBus working. I wr">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    sidebar: {"position":"left","display":"post"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://ideask.cf/2017/04/27/bbb-build-can/"/>





  <title> BBB添加CAN支持 | Jason Lin </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  


<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', '85*****1', 'auto');
  ga('send', 'pageview');
</script>


  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?87980c**************99ec5e26fb5";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>








  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">Jason Lin</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
    
      <p class="site-subtitle">Jason's Blog</p>
    
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-message">
          <a href="/message" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-external-link"></i> <br />
            
            留言
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup">
 <span class="search-icon fa fa-search"></span>
 <input type="text" id="local-search-input">
 <div id="local-search-result"></div>
 <span class="popup-btn-close">close</span>
</div>


    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
  <link itemprop="mainEntityOfPage" href="http://ideask.cf/2017/04/27/bbb-build-can/">

  <span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <meta itemprop="name" content="Jason Lin">
    <meta itemprop="description" content="">
    <meta itemprop="image" content="/images/avatar.gif">
  </span>

  <span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="Jason Lin">
    <span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
      <img style="display:none;" itemprop="url image" alt="Jason Lin" src="">
    </span>
  </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                BBB添加CAN支持
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2017-04-27T17:56:10+08:00">
                2017-04-27
              </time>
			  </span>
			
			<span>
    
			<span>更新于</span>
			<time>
			2017-04-27
			17:56:10
			</time>
			</span>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/BeagleBoneBlack/" itemprop="url" rel="index">
                    <span itemprop="name">BeagleBoneBlack</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
              <span class="post-comments-count">
                <span class="post-meta-divider">|</span>
                <span class="post-meta-item-icon">
                  <i class="fa fa-comment-o"></i>
                </span>
                <a href="/2017/04/27/bbb-build-can/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count ds-thread-count" data-thread-key="2017/04/27/bbb-build-can/" itemprop="commentCount"></span>
                </a>
              </span>
            
          

          

          
          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>A few months back I got hold of my first BeagleBone Black (BBB) with the intention of installing it in my car as a trackday data logger. First step in this endeavor was to get the CANBus working. I wrote this up here, but I’m shutting down that (poorly designed) site and have come up with a better way of enabling CAN so here goes.</p>
<p>First up, I’m assuming you are either running the latest Angstrom image (see here), or Ubuntu with the patched device tree compiler (see here). This ensures you have a device tree compiler which is capable of compiling overlays. So with that out of the way…</p>
<p>Enabling DCAN1</p>
<p>Update 26th August 2013: This original post focused on enabling dcan1, as these pins are available by default. If you’d like to enable dcan0 (At the expense of i2c2, possibly breaking any capes you have plugged in!), skip to the bottom of the post</p>
<p>To enable CAN (specifically dcan1), we need to write a device tree overlay which will enable the device and set the pin muxing. For those of you who just want the answer, here’s the overlay.</p>
<p>BB-DCAN1-00A0.dts</p>
<pre><code class="bash">/dts-v1/;
/plugin/;

/ {
    compatible = <span class="string">"ti,beaglebone"</span>, <span class="string">"ti,beaglebone-black"</span>;

    /* identification */
    part-number = <span class="string">"dcan1pinmux"</span>;

    fragment@0 {
        target = &lt;&amp;am33xx_pinmux&gt;;
        __overlay__ {
            dcan1_pins_s0: dcan1_pins_s0 {
                pinctrl-single,pins = &lt;
                    0x180 0x12  /* d_can1_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */
                    0x184 0x32  /* d_can1_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */
                &gt;;
            };
        };
    };

    fragment@1 {
        target = &lt;&amp;dcan1&gt;;
        __overlay__ {
             <span class="comment">#address-cells = &lt;1&gt;;</span>
             <span class="comment">#size-cells = &lt;0&gt;;</span>

             status = <span class="string">"okay"</span>;
             pinctrl-names = <span class="string">"default"</span>;
             pinctrl-0 = &lt;&amp;dcan1_pins_s0&gt;;
        };
    };
};
</code></pre>
<p>There are two important parts to the overlay, fragment@0 and fragment@1. We’ll look at each of those in turn.</p>
<p>fragment@0 is responsible for setting the pin mux. The two lines of hex (15-16) represent pairs of ‘pin’ register and ‘mode’ value.</p>
<p>Update 20th August 2013: I’ve created a spreadsheet to simplify the determination of register offset and mode values so you no longer have to dig through datasheets. The dcan1 signals can be found on pins P9 _24 and P9_26, both Mode 2. Use the register value worksheet to determine the correct pinmux values (Fast slew,  input for rx/output for tx, pull up, mode 2).</p>
<p>To find the correct register you first need to find out the name of the pins from the BBB SRM. Referring to Table 11 in the SRM, you can find the dcan1 signals are exposed on pins 24 (UART1_TXD) and 26 (UART1_RXD).</p>
<p>Now, diving in to the AM3359 Technical Reference Manual. In Table 9-10 (on page 759!) you can find the two registers conf_uart1_txd (0x980) and conf_uart1_rxd (0x984). These pin configuration registers start at 0x800, therefore the offset values are 0x180 and 0x184 respectively.</p>
<p>The detail of these registers can be found in Section 9.3.51, letting you calculate the correct values for dcan1.</p>
<p>Pin    Slew Rate    Input    Pull Up    Pull Up    Mode    Mode    Mode    In Hex</p>
<pre><code class="bash">d_can1_tx (0x180)    0    0    1    0    0    1    0    0x12
d_can1_rx (0x184)    0    1    1    0    0    1    0    0x32
</code></pre>
<p>That’s it for fragment@0, on to fragment@1. This section enables the CAN device. Firstly, on line 23, we identify the device we want to enable as dcan1. Then we specify that we want the device enabled by setting it’s status to “okay” on line 28. Finally, we associate the pin mux created in fragment@0 with the device, line 30.</p>
<p>To compile this overlay, save it as BB-DCAN1-00A0.dts (the dts extension referring to a device tree source file). Then execute the following command.</p>
<pre><code class="bash">dtc -O dtb -o BB-DCAN1-00A0.dtbo -b 0 -@ BB-DCAN1-00A0.dts
</code></pre>
<p>This will create the overlay binary BB-DCAN1-00A0.dtbo. If you get an error about the -@ option being unrecognised then you are likely on Ubuntu without the patched version of dtc (see here).</p>
<p>To use the overlay simply copy it to /lib/firmware</p>
<pre><code class="bash">sudo cp BB-DCAN1-00A0.dtbo /lib/firmware
</code></pre>
<p>And execute the following (note you must be logged in as root to do this, sudo will not work!)</p>
<pre><code class="bash"><span class="built_in">echo</span> BB-DCAN1 &gt; /sys/devices/bone_capemgr.*/slots
</code></pre>
<p>Check with dmesg to see if this worked, you should see something like this</p>
<pre><code class="bash">dmesg | tail -n15
[   17.878323] init: plymouth-stop pre-start process (796) terminated with status 1
[  283.946706] bone-capemgr bone_capemgr.8: part_number <span class="string">'BB-DCAN1'</span>, version <span class="string">'N/A'</span>
[  283.946892] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: generic override</span>
[  283.946944] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 9
[  283.946996] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: 'Override Board Name,00A0,Override Manuf,BB-DCAN1'</span>
[  283.947270] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: Requesting part number/version based 'BB-DCAN1-00A0.dtbo</span>
[  283.947323] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: Requesting firmware 'BB-DCAN1-00A0.dtbo' for board-name 'Override Board Name', version '00A0'</span>
[  283.951368] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: dtbo 'BB-DCAN1-00A0.dtbo' loaded; converting to live tree</span>
[  283.952035] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: #2 overlays</span>
[  283.953133] platform 481d0000.d_can: <span class="built_in">alias</span> fck already exists
[  283.962225] bone-capemgr bone_capemgr.8: slot <span class="comment">#9: Applied #2 overlays.</span>
[  284.034183] CAN device driver interface
[  284.071999] c_can_platform 481d0000.d_can: invalid resource
[  284.078088] c_can_platform 481d0000.d_can: control memory is not used <span class="keyword">for</span> raminit
[  284.084553] c_can_platform 481d0000.d_can: c_can_platform device registered (regs=fa1d0000, irq=71)
If you have something to hook up to (don<span class="string">'t forget to go through a transceiver, or bad things will happen), you can test everything is up and working with can-utils. First, make sure you have all the relevant modules loaded.</span>
</code></pre>
<pre><code class="bash">sudo modprobe can
sudo modprobe can-dev
sudo modprobe can-raw
</code></pre>
<p>Get and build can-utils</p>
<pre><code class="bash">svn co svn://svn.berlios.de/socketcan/trunk
<span class="built_in">cd</span> trunk/can-utils/
make
</code></pre>
<p>Set up the bus speed and enable it</p>
<pre><code class="bash">sudo ip link <span class="built_in">set</span> can0 up <span class="built_in">type</span> can bitrate 500000
sudo ifconfig can0 up
</code></pre>
<p>Now you can use either cansend or candump to test your bus.</p>
<p>Unfortunately, I’ve discovered my car is more rust than chassis so the track days are going to have to wait. BBB has been repurposed to other projects, more details on these coming soon…</p>
<p>Enabling DCAN0</p>
<p>Update 26th August 2013: After the comment from Marco below, I’ve put this section in to enable DCAN0.</p>
<p>To enable dcan0, you’ll need an overlay similar to that for dcan1. Marco posted one below, but it seems the comment system strips angled brackets for fear of HTML tags, so here is one I made.</p>
<p>BB-DCAN0-00A0.dts</p>
<pre><code class="bash">/dts-v1/;
/plugin/;

/ {
    compatible = <span class="string">"ti,beaglebone"</span>, <span class="string">"ti,beaglebone-black"</span>;

    /* identification */
    part-number = <span class="string">"dcan0pinmux"</span>;

    fragment@0 {
        target = &lt;&amp;am33xx_pinmux&gt;;
        __overlay__ {
            dcan0_pins_s0: dcan0_pins_s0 {
                pinctrl-single,pins = &lt;
                    0x178 0x12  /* d_can0_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */
                    0x17C 0x32  /* d_can0_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */
                &gt;;
            };
        };
    };

    fragment@1 {
        target = &lt;&amp;dcan0&gt;;
        __overlay__ {
             <span class="comment">#address-cells = &lt;1&gt;;</span>
             <span class="comment">#size-cells = &lt;0&gt;;</span>

             status = <span class="string">"okay"</span>;
             pinctrl-names = <span class="string">"default"</span>;
             pinctrl-0 = &lt;&amp;dcan0_pins_s0&gt;;
        };
    };
};
</code></pre>
<p>We can build and install this in the same way</p>
<pre><code class="bash">dtc -O dtb -o BB-DCAN0-00A0.dtbo -b 0 -@ BB-DCAN0-00A0.dts
sudo cp BB-DCAN0-00A0.dtbo /lib/firmware
</code></pre>
<p>However, if you try to enable dcan0 now you will get an error about the i2c pins (see Marco’s comment). This is because the i2c2 pins are enabled by default and take precedence over any overlay. Before we continue I should mention that the i2c2 pins are used by the BBB to identify capes, and enable devices/pinmuxes appropriately, everything I do from here on is likely to stop any capes working!.</p>
<p>Another warning: This process involves modifying the default device tree binary. If you do this incorrectly, your BBB will not boot. If you’re messing with the eMMC image, I can’t guarantee it can be reflashed either (although I see no reason why it shouldn’t be possible). You’re following this guide at your own risk, if it breaks your BBB it’s not my fault! I do all my hacking on an Ubuntu flashed SD card, so if it goes wrong (and it often does!) I can stick the card in my PC and undo any changes. eMMC users, continue at your own risk…</p>
<p>Unfortunately, we can’t simply disable i2c2 with an overlay (I have tried, it crashed my BBB!). We also can’t switch off the i2c2 device, because it is used by bone_capemgr and disabling it seems to make /sys/devices/bone_capemgr.*/slots disappear, meaning we can’t enable overlays! So, my work around is simply to prevent the i2c2 device setting its pinmux and claiming the dcan0 pins. In this state, as far as bone_capemgr is concerned, the i2c2 pins are perpetually disconnected (but the device still exists in /dev/).</p>
<p>To stop i2c2 from setting its pinmux, we need to modify the default device tree binary, and to do this we need the source files. If you built your kernel from scratch you will have them lying around somewhere, but if not you can grab them from Derek Molloy’s git repository (Note, I’m assuming the 3.8.13 kernel here).</p>
<pre><code class="bash">git <span class="built_in">clone</span> https://github.com/derekmolloy/boneDeviceTree.git
<span class="built_in">cd</span> boneDeviceTree/DTSource3.8.13/
</code></pre>
<p>Open up am335x-bone-common.dtsi and go to line 401 (pass the -c flag to nano to show line numbers). This is the section concerning i2c2.</p>
<pre><code class="bash">nano -c am335x-bone-common.dtsi
</code></pre>
<p>am335x-bone-common.dtsi</p>
<pre><code class="bash">&amp;i2c2 {
    status = <span class="string">"okay"</span>;
    pinctrl-names = <span class="string">"default"</span>;
    pinctrl-0 = &lt;&amp;i2c2_pins&gt;;

    clock-frequency = &lt;100000&gt;;

    cape_eeprom0: cape_eeprom0@54 {
        compatible = <span class="string">"at,24c256"</span>;
        reg = &lt;0x54&gt;;
    };

    cape_eeprom1: cape_eeprom1@55 {
        compatible = <span class="string">"at,24c256"</span>;
        reg = &lt;0x55&gt;;
    };

    cape_eeprom2: cape_eeprom2@56 {
        compatible = <span class="string">"at,24c256"</span>;
        reg = &lt;0x56&gt;;
    };

    cape_eeprom3: cape_eeprom3@57 {
        compatible = <span class="string">"at,24c256"</span>;
        reg = &lt;0x57&gt;;
    };
};
</code></pre>
<p>To prevent the pinmux from being applied, simply comment out </p>
<p>am335x-bone-common.dtsi</p>
<p>//  pinctrl-0 = &lt;&amp;i2c2_pins&gt;;<br>Save and exit, then build with (note, you’re not building the file you just edited!)</p>
<pre><code class="bash">dtc -O dtb -o am335x-boneblack.dtb -b 0 -@ am335x-boneblack.dts
</code></pre>
<p>Before overwriting your default device tree binary, back it up</p>
<pre><code class="bash">sudo mv /boot/uboot/dtbs/am335x-boneblack.dtb /boot/uboot/dtbs/am335x-boneblack.orig.dtb
</code></pre>
<p>Now move your new binary in to place</p>
<p>sudo mv am335x-boneblack.dtb /boot/uboot/dtbs/<br>You’ll get an error about preserving permissions, you can safely ignore this.</p>
<p>Now reboot your BBB and the i2c2 pinmux will not be applied. Now you should be able to enable dcan0 in much the same way as dcan1. As root (not sudo!)</p>
<pre><code class="bash"><span class="built_in">echo</span> BB-DCAN0 &gt; /sys/devices/bone_capemgr.*/slots
</code></pre>
<p>Now grab can-utils and play around with the bus (see above for dcan1).</p>
<p>If you plan to use dcan0 and dcan1, I believe the device driver numbering is based on the order the devices are enabled. So enable dcan0 before dcan1 so that your calls to ip, ifconfig, candump, etc… all make sense!</p>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        
  <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
    <div>如果文章对您有用请随意打赏，谢谢支持！</div>
    <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
      <span>赏</span>
    </button>
    <div id="QR" style="display: none;">
      
        <div id="wechat" style="display: inline-block">
          <img id="wechat_qr" src="/images/w.png" alt="Jason Lin WeChat Pay"/>
          <p>微信打赏</p>
        </div>
      
      
        <div id="alipay" style="display: inline-block">
          <img id="alipay_qr" src="/images/z.jpg" alt="Jason Lin Alipay"/>
          <p>支付宝打赏</p>
        </div>
      
    </div>
  </div>


      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/BeagleBoneBlack/" rel="tag"># BeagleBoneBlack</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/04/27/bbb-build-spi/" rel="next" title="BBB添加SPI支持">
                <i class="fa fa-chevron-left"></i> BBB添加SPI支持
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
        <div class="ds-share flat" data-thread-key="2017/04/27/bbb-build-can/"
     data-title="BBB添加CAN支持"
     data-content=""
     data-url="http://ideask.cf/2017/04/27/bbb-build-can/">
  <div class="ds-share-inline">
    <ul  class="ds-share-icons-16">

      <li data-toggle="ds-share-icons-more"><a class="ds-more" href="javascript:void(0);">分享到：</a></li>
      <li><a class="ds-weibo" href="javascript:void(0);" data-service="weibo">微博</a></li>
      <li><a class="ds-qzone" href="javascript:void(0);" data-service="qzone">QQ空间</a></li>
      <li><a class="ds-qqt" href="javascript:void(0);" data-service="qqt">腾讯微博</a></li>
      <li><a class="ds-wechat" href="javascript:void(0);" data-service="wechat">微信</a></li>

    </ul>
    <div class="ds-share-icons-more">
    </div>
  </div>
</div>
      
    </div>
  </div>

          
          </div>
          


          
  <div class="comments" id="comments">
    
      <div class="ds-thread" data-thread-key="2017/04/27/bbb-build-can/"
           data-title="BBB添加CAN支持" data-url="http://ideask.cf/2017/04/27/bbb-build-can/">
      </div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      

      <section class="site-overview sidebar-panel sidebar-panel-active">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/images/avatar.gif"
               alt="Jason Lin" />
          <p class="site-author-name" itemprop="name">Jason Lin</p>
          <p class="site-description motion-element" itemprop="description">embedded system engineer</p>
        </div>
        <nav class="site-state motion-element">
        
          
            <div class="site-state-item site-state-posts">
              <a href="/archives">
                <span class="site-state-item-count">15</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">9</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">9</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/ideask" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  GitHub
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="https://twitter.com/ideask" target="_blank" title="Twitter">
                  
                    <i class="fa fa-fw fa-twitter"></i>
                  
                  Twitter
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/ideask" target="_blank" title="微博">
                  
                    <i class="fa fa-fw fa-weibo"></i>
                  
                  微博
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://douban.com/people/ideask" target="_blank" title="豆瓣">
                  
                    <i class="fa fa-fw fa-globe"></i>
                  
                  豆瓣
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://www.zhihu.com/people/ideask" target="_blank" title="知乎">
                  
                    <i class="fa fa-fw fa-globe"></i>
                  
                  知乎
                </a>
              </span>
            
          
        </div>

        
        

        
        
          <div class="links-of-blogroll motion-element links-of-blogroll-inline">
            <div class="links-of-blogroll-title">
              <i class="fa  fa-fw fa-globe"></i>
              友情链接
            </div>
            <ul class="links-of-blogroll-list">
              
                <li class="links-of-blogroll-item">
                  <a href="http://www.jyu.edu.cn/" title="嘉应大学" target="_blank">嘉应大学</a>
                </li>
              
            </ul>
          </div>
        

        


      </section>

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2017</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Jason Lin</span>
</div>



        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  




  
  <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.0"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.0"></script>



  

  
    
  

  <script type="text/javascript">
    var duoshuoQuery = {short_name:"ideask"};
    (function() {
      var ds = document.createElement('script');
      ds.type = 'text/javascript';ds.async = true;
      ds.id = 'duoshuo-script';
      ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
      ds.charset = 'UTF-8';
      (document.getElementsByTagName('head')[0]
      || document.getElementsByTagName('body')[0]).appendChild(ds);
    })();
  </script>

  
    
    
    <script src="/lib/ua-parser-js/dist/ua-parser.min.js?v=0.7.9"></script>
    <script src="/js/src/hook-duoshuo.js"></script>
  












  
  
  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length == 0) {
      search_path = "search.xml";
    }
    var path = "/" + search_path;
    // monitor main search box;

    function proceedsearch() {
      $("body").append('<div class="popoverlay">').css('overflow', 'hidden');
      $('.popup').toggle();
    }
    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';
      $.ajax({
        url: path,
        dataType: "xml",
        async: true,
        success: function( xmlResponse ) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = $( "entry", xmlResponse ).map(function() {
            return {
              title: $( "title", this ).text(),
              content: $("content",this).text(),
              url: $( "url" , this).text()
            };
          }).get();
          var $input = document.getElementById(search_id);
          var $resultContent = document.getElementById(content_id);
          $input.addEventListener('input', function(){
            var matchcounts = 0;
            var str='<ul class=\"search-result-list\">';
            var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
            $resultContent.innerHTML = "";
            if (this.value.trim().length > 1) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var content_index = [];
                var data_title = data.title.trim().toLowerCase();
                var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
                var data_url = decodeURIComponent(data.url);
                var index_title = -1;
                var index_content = -1;
                var first_occur = -1;
                // only match artiles with not empty titles and contents
                if(data_title != '') {
                  keywords.forEach(function(keyword, i) {
                    index_title = data_title.indexOf(keyword);
                    index_content = data_content.indexOf(keyword);
                    if( index_title >= 0 || index_content >= 0 ){
                      isMatch = true;
                      if (i == 0) {
                        first_occur = index_content;
                      }
                    }

                  });
                }
                // show search results
                if (isMatch) {
                  matchcounts += 1;
                  str += "<li><a href='"+ data_url +"' class='search-result-title'>"+ data_title +"</a>";
                  var content = data.content.trim().replace(/<[^>]+>/g,"");
                  if (first_occur >= 0) {
                    // cut out 100 characters
                    var start = first_occur - 20;
                    var end = first_occur + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if(start == 0){
                      end = 50;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    var match_content = content.substring(start, end);
                    // highlight all keywords
                    keywords.forEach(function(keyword){
                      var regS = new RegExp(keyword, "gi");
                      match_content = match_content.replace(regS, "<b class=\"search-keyword\">"+keyword+"</b>");
                    });

                    str += "<p class=\"search-result\">" + match_content +"...</p>"
                  }
                  str += "</li>";
                }
              })};
            str += "</ul>";
            if (matchcounts == 0) { str = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>' }
            if (keywords == "") { str = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>' }
            $resultContent.innerHTML = str;
          });
          proceedsearch();
        }
      });}

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched == false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(function(e){
      $('.popup').hide();
      $(".popoverlay").remove();
      $('body').css('overflow', '');
    });
    $('.popup').click(function(e){
      e.stopPropagation();
    });
  </script>


  

  
  

  


</body>
</html>
